﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Transactions;
using Newtonsoft.Json;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.ServiceComponent.DAC.Service;
using System.Reflection;
using System.Data;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Base.Dao;

namespace T.FAS.Runtime.DataModel.Dao
{
    /// <summary>
    /// CDO ELB数据访问类
    /// </summary>
    public class CompositeDataObjectELBDao : DaoService<CompositeDataObject>, ICompositeDataObjectDao
    {
        #region Fields & Properties
        public const string MetaDataID = DataModelConst.CDOMetaType;
        public const string MetaDataName = "复合数据对象";

        public override string TableName => "FAS_CompositeDataObject";
        public override string IDColumnName => "ID";
        public override List<string> ExceptColumnName { get; } =
             DaoUtil.GetExceptionColumn<CompositeDataObject>(
                new List<string>
                {
                    "IsLogicDelete",
                    EntityTools.ProjectBranchID,
                }
            );
        private readonly CompositeNodeObjectELBDao _compositeNodeObjectELBDao = new CompositeNodeObjectELBDao();
        private readonly CompositeNodeObjectElementELBDao _nodeObjectElementELBDao = new CompositeNodeObjectElementELBDao();
        private readonly AssociationELBDao _associationELBDao = new AssociationELBDao();
        private readonly AssociateItemELBDao _associateItemELBDao = new AssociateItemELBDao();
        private readonly AssociationRefElementELBDao _associationRefElementELBDao = new AssociationRefElementELBDao();
        #endregion

        #region Override Funcs
        //public override Dictionary<string, object> GetDataMapping(CompositeDataObject data)
        //{
        //    var datas = base.GetDataMapping(data);
        //    datas.Remove(nameof(data.EnableChangeLog));
        //    datas.Add(nameof(data.EnableChangeLog), (bool)data.EnableChangeLog);
        //    return datas;
        //}

        public override CompositeDataObject ConvertToObject(Dictionary<string, PropertyInfo> columns, DataRow row)
        {
            var myCol = new Dictionary<string, PropertyInfo>(base.Columns);
            myCol.Remove("EnableChangeLog");
            var data = base.ConvertToObject(myCol, row);
            //if (row["EnableChangeLog"] != null)
            //    data.EnableChangeLog = int.Parse(Convert.ToString(row["EnableChangeLog"])) == 0 ? false : true;

            string isEnableChangeLogVal = row["EnableChangeLog"]?.ToString();
            if (!string.IsNullOrEmpty(isEnableChangeLogVal))
            {
                if (int.TryParse(isEnableChangeLogVal, out int isEnableChangeLogInt))
                {
                    data.EnableChangeLog = isEnableChangeLogInt == 0 ? false : true;
                }
                else
                    data.EnableChangeLog = false;
            }
            else
                data.EnableChangeLog = false;
            return data;
        }

        public override Dictionary<string, PropertyInfo> GetColumns()
        {
            return DaoServiceExtension.GetAllColumns<CompositeDataObject>(base.GetColumns());
        }
        #endregion

        public CompositeDataObjectELBDao(): base()
        {
            DBName = "TFAS";
        }

        #region 获取元数据内容
        /// <summary>
        /// 获取元数据内容
        /// </summary>
        /// <param name="metaDataId"></param>
        /// <returns></returns>
        public CompositeDataObject GetCompositeDataObject(string metaDataId)
        {
            var result = new CompositeDataObject();
            if (string.IsNullOrEmpty(metaDataId))
            {
                return result;
            }
            result = base.GetObject(metaDataId);
            return result;
        }

        public List<CompositeDataObject> GetCompositeDataObjects()
        {
            var result = new List<CompositeDataObject>();
            List<object> objects = base.GetObjectsByFilter("1=1");
            if (objects != null)
            {
                objects.ForEach(obj => result.Add(obj as CompositeDataObject));
            }
            return result;
        }

        public List<CompositeDataObject> GetCompositeDataObjectsByCondition(Dictionary<string, object> condition)
        {
            var result = new List<CompositeDataObject>();
            List<object> objects = base.GetObjectsByFilter("1=1");
            if (objects != null)
            {
                objects.ForEach(obj => result.Add(obj as CompositeDataObject));
            }
            return result;
        }

        public int GetCompositeDataObjectCountByCondition(Dictionary<string, object> condition)
        {
            return base.GetObjectsByFilter("1=1").Count();
        }

        #endregion

        /// <summary>
        /// 保存CDO
        /// </summary>
        /// <param name="cdo"></param>
        public void SaveCompositeDataObject(CompositeDataObject cdo)
        {
            try
            {
                base.Add(new List<object> { cdo });
                _compositeNodeObjectELBDao.Add(cdo.CompositeNodeObjects);
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.CDO.CreateError, $"{MetaDataName}:{cdo.Code}保存失败！", e);
            }
        }

        /// <summary>
        /// 保存CNOElement
        /// </summary>
        /// <param name="nodes"></param>
        public void SaveCompositeNodeObjectElements(List<CompositeNodeObjectElement> elements)
        {
            if (elements != null)
                _nodeObjectElementELBDao.CreateCompositeNodeObjectElement(elements);
        }

        /// <summary>
        /// 保存Association
        /// </summary>
        /// <param name="associations"></param>
        public void SaveDomainAssociation(List<Association> associations)
        {
            if (associations != null)
                _associationELBDao.Add(associations);
        }

        public void SaveDomainAssociationItem(List<AssociateItem> associateItems)
        {
            if (associateItems != null)
                _associateItemELBDao.Add(associateItems);
        }

        public void SaveAssociationRefElements(List<AssociationRefElement> refElements)
        {
            if (refElements != null)
                _associationRefElementELBDao.Add(refElements);
        }

        /// <summary>
        /// 删除CDO
        /// </summary>
        /// <param name="id"></param>
        public void DeleteCompositeDataObject(string id)
        {
            using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
            {
                _compositeNodeObjectELBDao.DeleteCompositeNodeObjects(id);
                base.Delete(new List<string> { id });
                scope.Complete();
            }
        }

        /// <summary>
        /// 批量删除领域对象
        /// </summary>
        /// <param name="id">领域对象ID</param>
        public void DeleteCompositeDataObjects(List<string> ids)
        {
            foreach (var id in ids)
            {
                _compositeNodeObjectELBDao.DeleteCompositeNodeObjects(id);
                base.Delete(new List<string> { id });
            }
        }
    }
}
